//-----------------------------------------------------------------------------
// Name: DisplayManager.cpp
// Auth: Bradford J. Smith & Robert Darty
// Desc: contains all of the interface required to manipulate the view as well
//		as any additional state information.
//-----------------------------------------------------------------------------

#include "DisplayManager.h"
#include "Assert.h"
#include "SharedConstants.h"
#include <iostream>
#include <GL/glut.h>
#include <Windows.h>
#include <sstream>
#include <iomanip>
#include <math.h>
#include "corona/corona.h"
#include "GunManager.h"
#include "Display.h"
#include "Bounding.h"
#include "Bullet.h"
#include "InanimateObject.h"
#include "InanimateObjectManager.h"
#include "CollisionDetect.h"
using namespace std;
//-----------------------------------------------------------------------------
// Constants:
//-----------------------------------------------------------------------------
const float kInitialCameraPitch = 0.0f;
const float kInitialCameraHeading = 360.0f;
const float kInitialCameraOffsetOrtho = 2.0f;
const float kInitialCameraOffsetProjection = 20.0f;

const float kMinCameraOffset = 0.5f;
DWORD gLastTickCountDM = 0;

//cDisplayManager gDisplayManager;

//Calculates the length of a vector
float VectorLength(const tVector3f& vector)
{
	return (float) sqrt((vector[0] * vector[0]) + (vector[1] * vector[1]) + (vector[2] * vector[2]));
}

//-----------------------------------------------------------------------------
// cDisplayManager:
//-----------------------------------------------------------------------------
cDisplayManager::cDisplayManager() :
	mWindowWidth(kInitialWindowWidth),
	mWindowHeight(kInitialWindowHeight),
	mProjectionMode(kPerspective),
	mCameraPitch(kInitialCameraPitch),
	mCameraHeading(kInitialCameraHeading),
	mCameraOffset(kInitialCameraOffsetOrtho),
	mHealth(100),
	mStatus(true),
	mPoints(0),
	mDamageDirection(0),
	mDead(0)
{
	// Start the camera looking at the origin from down the z-Axis
	mCameraPosition[0] = 0.0f;
	mCameraPosition[1] = 1.9f;
	mCameraPosition[2] = -225.0f;
	//mCameraPosition[2] = 195.0f;
	mCameraHeading = 0.0f;
	mCameraPitch = 0.0f;
	mStrafeSpeed = 0.0f;
	mForwardSpeed = 0.0f;
	AddBody(mCameraPosition[0], mCameraPosition[1]-1.65f, mCameraPosition[2], 0.3f);
	AddBody(mCameraPosition[0], mCameraPosition[1]-1.15f, mCameraPosition[2], 0.3f);
	AddBody(mCameraPosition[0], mCameraPosition[1]-0.65f, mCameraPosition[2], 0.3f);
	AddBody(mCameraPosition[0], mCameraPosition[1]-0.15f, mCameraPosition[2], 0.3f);
	mVictory=false;
}

cDisplayManager::~cDisplayManager()
{

}

cDisplayManager* cDisplayManager::GetDisplayManager()
{
	return this;
}

//Sets initial bullets
void cDisplayManager::SetInitBullets(int b)
{
	mBullets = b;
}

//Gets victory status
bool cDisplayManager::GetVictory()
{
	return mVictory;
}

//Sets victory status
void cDisplayManager::SetVictory(bool b)
{
	mVictory = b;
}

//Gets camera X
float cDisplayManager::GetCameraX()
{
	return mCameraPosition[0];
}

//Gets camera Y
float cDisplayManager::GetCameraY()
{
	return mCameraPosition[1];
}

//Gets camera Z
float cDisplayManager::GetCameraZ()
{
	return mCameraPosition[2];
}

//Gets direction x
float cDisplayManager::GetDirection1()
{
	return mDirection[0];
}
//GEts direction y
float cDisplayManager::GetDirection2()
{
	return mDirection[1];
}

//Gets directionZ
float cDisplayManager::GetDirection3()
{
	return mDirection[2];
}

//-----------------------------------------------------------------------------
void cDisplayManager::SetWindowArea(int width, int height)
{
	mWindowWidth = width;
	mWindowHeight = height;
}

//-----------------------------------------------------------------------------
// Returns the current Window Width - used to make sure HUD stays constant even when window resizes
int cDisplayManager::GetWindowWidth()
{
	return mWindowWidth;
}

//-----------------------------------------------------------------------------
//Returns window height
int cDisplayManager::GetWindowHeight()
{
	return mWindowHeight;
}

//-----------------------------------------------------------------------------
void cDisplayManager::SetPerspectiveMode()
{
	// update the mode and then force the projection to update
	mProjectionMode = kPerspective;
	UpdateProjection();
}

//-----------------------------------------------------------------------------
void cDisplayManager::SetOrthographicMode()
{
	// update the mode and then force the projection to update
	mProjectionMode = kOrthographic;
	UpdateProjection();
}

//-----------------------------------------------------------------------------
void cDisplayManager::UpdateProjection()
{
	// we are going to modify the projection matrix
	glMatrixMode(GL_PROJECTION);
	glLoadIdentity();

	switch (mProjectionMode)
	{
	case kOrthographic:
		{
			// create a basic orthographic projection
			glOrtho(-500.0, 500.0, -500.0, 500.0, -500.0, 500.0);

			// reset the camera offset to be a reasonable distance.
			mCameraOffset = kInitialCameraOffsetOrtho;
		}
		break;
	case kPerspective:
		{
			// compute the aspect ratio, being careful to cast to float
			float aspectRatio = (float)mWindowWidth / (float)mWindowHeight;

			// create a basic perspective projection
			gluPerspective(80.0f, aspectRatio, 0.2f, 210.0f);
		
			// reset the camera offset to be a reasonable distance.
			mCameraOffset = kInitialCameraOffsetProjection;
		}
		break;
	default:
		{
			// Unsupported mode!
			Assert(false);
		}
		break;
	}

	// reset the model view in any case.
	glMatrixMode(GL_MODELVIEW);
	glLoadIdentity();
}

//-----------------------------------------------------------------------------
void cDisplayManager::SetCameraPitch(float pitch)
{
	//Sets the Camera's pitch
	mCameraPitch = pitch;
}

//-----------------------------------------------------------------------------
void cDisplayManager::SetCameraHeading(float heading)
{
	//Sets the Camera Heading
	mCameraHeading = heading;
}

//-----------------------------------------------------------------------------
void cDisplayManager::SetCameraOffset(float offset)
{
	//Sets camera offset
	if (offset < kMinCameraOffset)
	{
		mCameraOffset = kMinCameraOffset;
	}
	else 
	{
		mCameraOffset = offset;
	}
}

//-----------------------------------------------------------------------------
float cDisplayManager::GetCameraPitch()
{
	//Gets pitch
	return mCameraPitch;
}

//-----------------------------------------------------------------------------
float cDisplayManager::GetCameraHeading()
{
	//Gets heading
	return mCameraHeading;
}

float cDisplayManager::GetCameraOffset()
{
	//Gets Offset
	return mCameraOffset;
}

cBounding* cDisplayManager::GetBoundingMaster()
{
    return &mMaster;
}

//-----------------------------------------------------------------------------

//Updates the Camera position - checks for collisions with inanimates
void cDisplayManager::UpdateCamera(float elapsedTimeS)
{
	// Test the assumptions of the camera
	Assert(mCameraOffset >= kMinCameraOffset);
	// reset the model view matrix to identity
	glMatrixMode(GL_MODELVIEW);
	glLoadIdentity();

	// get tuning values
	float kMaxVelocity = 5.0f; // meters per second
	float kMaxRotationVelocity = 2.0f; // radians per second
	float kRotationFriction = 0.4f; // percentage loss per second [0.0f - 1.0]
	float kMovementFriction = 0.2f; // percentage loss per second [0.0f - 1.0]

	// update rotation
	//Keeps a 0-360 degree scale
	if (mCameraHeading < 0.0f)
	{
		mCameraHeading = mCameraHeading+360.0f;
	}
	else if (mCameraHeading > 360.0f)
	{
		mCameraHeading = mCameraHeading - 360.0f;
	}


	// The F Directions are the directions relative to forward movement (converts to radians)
	float xFDirection = cos((mCameraHeading-90)*kDegreesToRadians);
	float zFDirection = cos((mCameraHeading)*kDegreesToRadians);
	// The S Directions are directions relative to strafing movement (converts to radians)
	float xSDirection = sin((mCameraHeading-90)*kDegreesToRadians);
	float zSDirection = sin((mCameraHeading)*kDegreesToRadians);

	
	cInanimateObjectManager* pInanimateObjectManager = GetInanimateObjectManager();
	
	list<cInanimateObject>* liInanimate = pInanimateObjectManager->GetInanimateList();
	list<cInanimateObject>::iterator itIAO;

	if(!liInanimate->empty())
	{

		itIAO = liInanimate->begin();

		bool Collision = false;
		
		for(itIAO; itIAO!=liInanimate->end();)
		{
			cBounding *aBounding = (&*itIAO)->GetBounding();

			float minX = aBounding->getMinX();
			float maxX = aBounding->getMaxX();
			float minZ = aBounding->getMinZ();
			float maxZ = aBounding->getMaxZ();

			float inanimateX = itIAO->GetPositionX();
			float inanimateZ = itIAO->GetPositionZ();

			float vectorX = mMaster.GetSphereX()-inanimateX;
			float vectorZ = mMaster.GetSphereZ()-inanimateZ;

			float vLen = sqrt((vectorX*vectorX)+(vectorZ*vectorZ));

			float percentage = mMaster.GetSphereRadius()/vLen;

			float testX = vectorX*percentage;
			float testZ = vectorZ*percentage;

			float x = mMaster.GetSphereX()-testX;
			float z = mMaster.GetSphereZ()-testZ;

			if((((x>minX)&&(x<maxX))||((x>maxX)&&(x<minX)))&&(((z>minZ)&&(z<maxZ))||((z>maxZ)&&(z<minZ))))
			{
				Collision = true;
			}
				
			if(!Collision)
			{
				mCameraPosition[0] += ((mForwardSpeed * elapsedTimeS) * xFDirection)+((mStrafeSpeed * elapsedTimeS) * xSDirection);
				mCameraPosition[2] += ((mForwardSpeed * elapsedTimeS) * zFDirection)+((mStrafeSpeed * elapsedTimeS) * zSDirection);
			}
			else
			{
				float a = maxX-mCameraPosition[0];
				float b = mCameraPosition[0]-minX;
				float c = maxZ-mCameraPosition[2];
				float d = mCameraPosition[2]-minZ;

				if(a<0)
				{
					a*=-1;
				}
				if(b<0)
				{
					b*=-1;
				}
				if(c<0)
				{
					c*=-1;
				}
				if(d<0)
				{
					d*=-1;
				}


				if(a<b)
				{
					if(c<d)
					{
						if(a<c)
						{
							mCameraPosition[0] = maxX+2.0f;
							Collision=false;
						}
						else
						{
							mCameraPosition[2] = maxZ+2.0f;
							Collision=false;
						}
					}
					else
					{
						if(a<d)
						{
							mCameraPosition[0] = maxX+2.0f;
							Collision=false;
						}
						else
						{
							mCameraPosition[2] = minZ-2.0f;
							Collision = false;
						}

					}
				}
				else
				{
					if(c<d)
					{
						if(b<c)
						{
							mCameraPosition[0] = minX-2.0f;
							Collision=false;
						}
						else
						{
							mCameraPosition[2] = maxZ+2.0f;
							Collision=false;
						}
					}
					else
					{
						if(b<d)
						{
							mCameraPosition[0] = minX-2.0f;
							Collision=false;
						}
						else
						{
							mCameraPosition[2] = minZ-2.0f;
							Collision=false;
						}

					}
				}
			}

			if(itIAO!=liInanimate->end())
			{
				itIAO++;
			}

		}

	}
	
	else
	{
	
		// Change the position of the camera based on Forward/Strafe speed & time elapsed
		mCameraPosition[0] += ((mForwardSpeed * elapsedTimeS) * xFDirection)+((mStrafeSpeed * elapsedTimeS) * xSDirection);
		mCameraPosition[2] += ((mForwardSpeed * elapsedTimeS) * zFDirection)+((mStrafeSpeed * elapsedTimeS) * zSDirection);

	}
	// cap pitch to avoid being directly above or below the center of interest.
	if (mCameraPitch > 69.9f)
	{
		mCameraPitch = 69.9f;
	}
	else if (mCameraPitch < -69.9f)
	{
		mCameraPitch = -69.9f;
	}

	// convert to radians
	float pitch = mCameraPitch * kDegreesToRadians;
	float heading = mCameraHeading * kDegreesToRadians;

	// convert the polar coordinates of heading and pitch to a direction
	//mDirection = {sin(heading) * cos(pitch), sin(pitch), cos(heading) * cos(pitch)};
	mDirection[0] = sin(heading)*cos(pitch);
	mDirection[1] = sin(pitch);
	mDirection[2] = cos(heading)*cos(pitch);
	
	// construct the actual camera COI using Position, direction and offset
	// the direction, and the offset.
	tVector3f cameraCOI;
	for (int i = 0; i < 3; ++i)
	{
		cameraCOI[i] = mCameraPosition[i] + (mDirection[i] * mCameraOffset);
	}

	// move the camera using the lookat data
	gluLookAt(mCameraPosition[0], mCameraPosition[1], mCameraPosition[2], 
			  cameraCOI[0], cameraCOI[1], cameraCOI[2], 
			  kUpVector[0], kUpVector[1], kUpVector[2]);
	
	//Update bullets if 0 bullets left
	if(mBullets == 0)
	{
		Reload(elapsedTimeS);
	}
	if(mFireRate == 1)
	{
		FireDelay(elapsedTimeS);
	}
	if(mHealth <= 0)
	{
		mStatus = false;
	}

	//Updates collision spheres
	UpdateBody(mCameraPosition[0], mCameraPosition[1]-1.65f, mCameraPosition[2], 0.3f, 0);
	UpdateBody(mCameraPosition[0], mCameraPosition[1]-1.15f, mCameraPosition[2], 0.3f, 1);
	UpdateBody(mCameraPosition[0], mCameraPosition[1]-0.65f, mCameraPosition[2], 0.3f, 2);
	UpdateBody(mCameraPosition[0], mCameraPosition[1]-0.15f, mCameraPosition[2], 0.3f, 2);

	mMaster.SetSphere(mCameraPosition[0], mCameraPosition[1]-0.9f, mCameraPosition[2], 1.1f, kSphereBody);
}

//Moves players (depricated)
void cDisplayManager::Move(eMoveMode mode)
{
	// adjust acceleration applied to the ship based on input
	switch (mode)
	{
	case kStartMoveRight:
		//Because strafing is bi-directional - right is represented 
		//by positive numbers, left by negative
		mStrafeSpeed = kPlayerSpeed;
		break;
	case kStartMoveLeft:
		mStrafeSpeed = -kPlayerSpeed;
		break;
	case kStopMoveRight:
		mStrafeSpeed=0.0f;
		break;
	case kStopMoveLeft:
		mStrafeSpeed=0.0f;
		break;
	case kStartMoveForward:
		//Forwards represented by positive numbers
		mForwardSpeed = kPlayerSpeed;
		break;
	case kStartMoveBackward:
		//negative by backwards
		mForwardSpeed = -kPlayerSpeed;
		break;
	case kStopMoveForward:
		mForwardSpeed = 0.0f;
		break;
	case kStopMoveBackward:
		mForwardSpeed = 0.0f;
		break;
	default:
		// unsupported mode!
		Assert(false);
		break;
	}
}

//-----------------------------------------------------------------------------
//Draws the heads up display
void cDisplayManager::DrawHUD(float elapsedTimeS)
{

	//Ensure Projection mode is selected
	glMatrixMode(GL_PROJECTION);
	//Push the matrix
	glPushMatrix();
	glLoadIdentity();
	//Set up 2d Ortho disply
	gluOrtho2D(0, mWindowWidth, 0, mWindowHeight);
	glScalef(1, -1, 1);
	glTranslatef(0, (float)-mWindowHeight, 0);

	//Switch to Model view
	glMatrixMode(GL_MODELVIEW);

	glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
	glLoadIdentity();
	glDisable(GL_LIGHTING);
	if(mDamageDirection!=0)
	{
		if(mDamageDirection==kDamageRight)
		{
			DrawVertWarningBar(mWindowWidth-50, mWindowHeight-200);
		}
		if(mDamageDirection==kDamageLeft)
		{
			DrawVertWarningBar(20, mWindowHeight-200);
		}
		if(mDamageDirection==kDamageBack)
		{
			DrawHorzWarningBar((mWindowWidth/2)-150, mWindowHeight-30);
		}

	}

	//Set the color for HUD output
	glColor3f(1.0f, 0.0f, 0.0f);

	//Protype for outputing health - will need changing once it's implemented
	if(mHealth<0)
	{
		mHealth=0;
	}
	string hp;
	stringstream out;
	out<<mHealth;
	hp=out.str();
	string strHealth("Health: "+hp);
	glRasterPos2i(20, 20);
	int len = (int)strHealth.size();
	for (int i = 0; i < len; i++)
	{
		glutBitmapCharacter(GLUT_BITMAP_HELVETICA_18, strHealth[i]);
	}
	/*if(mPoints<0)
	{
		mPoints=0;
	}*/

	string points;
	stringstream out2;
	out2<<mPoints;
	points=out2.str();
	string strPoints("Points: "+points);
	glRasterPos2i(20, 40);
	len = (int)strPoints.size();
	for (int i = 0; i < len; i++)
	{
		glutBitmapCharacter(GLUT_BITMAP_HELVETICA_18, strPoints[i]);
	}


	//string position;
	//stringstream pos;
	//pos<<"X: " << setprecision(2) << fixed  << mCameraPosition[0] << " Z: "<<setprecision(2) << fixed  <<  mCameraPosition[2];
	//position=pos.str();
	//string strPosition("Position: "+position);
	//glRasterPos2i(mWindowWidth/2, 20);
	//len = (int)strPosition.size();
	//for (int i = 0; i < len; i++)
	//{
	//	glutBitmapCharacter(GLUT_BITMAP_HELVETICA_18, strPosition[i]);
	//}

	if(mDead == 1)
	{
		static float reloadTime = 0.0f;
		static float currentTime = 2.0f;
		
		if(currentTime > reloadTime)
		{
			string strPointChange("-10!");
			glRasterPos2i(mWindowWidth/2-15, (mWindowHeight/2-100));
			len = (int)strPointChange.size();
			for (int i = 0; i < len; i++)
			{
				glutBitmapCharacter(GLUT_BITMAP_HELVETICA_18, strPointChange[i]);
			}
			currentTime -= elapsedTimeS;
		}
		else
		{
			currentTime = 2.0f;
			mDead = 0;
		}
	}

	else if(mDead == 2)
	{
		static float reloadTime = 0.0f;
		static float currentTime = 2.0f;
		
		if(currentTime > reloadTime)
		{
			string strPointChange("+10!");
			glRasterPos2i(mWindowWidth/2-15, (mWindowHeight/2-100));
			len = (int)strPointChange.size();
			for (int i = 0; i < len; i++)
			{
				glutBitmapCharacter(GLUT_BITMAP_HELVETICA_18, strPointChange[i]);
			}
			currentTime -= elapsedTimeS;
		}
		else
		{
			currentTime = 2.0f;
			mDead = 0;
		}
	}

	else if(mDead == 3)
	{
		static float reloadTime = 0.0f;
		static float currentTime = 2.0f;
		
		if(currentTime > reloadTime)
		{
			string strPointChange("-20!");
			glRasterPos2i(mWindowWidth/2-15, (mWindowHeight/2-100));
			len = (int)strPointChange.size();
			for (int i = 0; i < len; i++)
			{
				glutBitmapCharacter(GLUT_BITMAP_HELVETICA_18, strPointChange[i]);
			}
			currentTime -= elapsedTimeS;
		}
		else
		{
			currentTime = 2.0f;
			mDead = 0;
		}
	}

	//IF the bullets are at 0 - display the reloading text
	if(mBullets == 0)
	{
		static float reloadTime = 1.0f;
		static float currentTime = 2.0f;
		
		if(currentTime > reloadTime)
		{
			string strReload("Reloading complete in 2 seconds");
			glRasterPos2i(mWindowWidth/2-100, mWindowHeight/2-150);
			int len = (int)strReload.size();
			for (int i = 0; i < len; i++)
			{
				glutBitmapCharacter(GLUT_BITMAP_HELVETICA_18, strReload[i]);
			}
			currentTime -= elapsedTimeS;
		}

		else if(currentTime < reloadTime && currentTime > 0.0f)
		{
			string strReload("Reloading complete in 1 second");
			glRasterPos2i(mWindowWidth/2-100, mWindowHeight/2-150);
			int len = (int)strReload.size();
			for (int i = 0; i < len; i++)
			{
				glutBitmapCharacter(GLUT_BITMAP_HELVETICA_18, strReload[i]);
			}
			currentTime -= elapsedTimeS;
		}
		else
		{
			currentTime = 2.0f;
		}
	}

	if(!mStatus)
	{
		string strGameOver("Game Over - press q to quit!");
		glRasterPos2i(mWindowWidth/2-125, mWindowHeight/2-25);
		int len = (int)strGameOver.size();
		for(int i=0;i<len;i++)
		{
			glutBitmapCharacter(GLUT_BITMAP_HELVETICA_18, strGameOver[i]);
		}

		if(mPoints >= 800)
		{
			string strGrade("Grade: A");
			glRasterPos2i(mWindowWidth/2-125, mWindowHeight/2-5);
			len = (int)strGrade.size();
			for(int i=0;i<len;i++)
			{
				glutBitmapCharacter(GLUT_BITMAP_HELVETICA_18, strGrade[i]);
			}
		}
		else if(mPoints < 800 && mPoints >= 700 )
		{
			string strGrade("Grade: B");
			glRasterPos2i(mWindowWidth/2-125, mWindowHeight/2-5);
			len = (int)strGrade.size();
			for(int i=0;i<len;i++)
			{
				glutBitmapCharacter(GLUT_BITMAP_HELVETICA_18, strGrade[i]);
			}
		}
		else if(mPoints < 700 && mPoints >= 550)
		{
			string strGrade("Grade: C");
			glRasterPos2i(mWindowWidth/2-125, mWindowHeight/2-5);
			len = (int)strGrade.size();
			for(int i=0;i<len;i++)
			{
				glutBitmapCharacter(GLUT_BITMAP_HELVETICA_18, strGrade[i]);
			}
		}
		else if(mPoints < 550 && mPoints >= 300)
		{
			string strGrade("Grade: D");
			glRasterPos2i(mWindowWidth/2-125, mWindowHeight/2-5);
			len = (int)strGrade.size();
			for(int i=0;i<len;i++)
			{
				glutBitmapCharacter(GLUT_BITMAP_HELVETICA_18, strGrade[i]);
			}
		}
		else if(mPoints < 300 && mPoints >= 150)
		{
			string strGrade("Grade: E");
			glRasterPos2i(mWindowWidth/2-125, mWindowHeight/2-5);
			len = (int)strGrade.size();
			for(int i=0;i<len;i++)
			{
				glutBitmapCharacter(GLUT_BITMAP_HELVETICA_18, strGrade[i]);
			}
		}
		else 
		{
			string strGrade("Grade: F");
			glRasterPos2i(mWindowWidth/2-125, mWindowHeight/2-5);
			len = (int)strGrade.size();
			for(int i=0;i<len;i++)
			{
				glutBitmapCharacter(GLUT_BITMAP_HELVETICA_18, strGrade[i]);
			}
		}
	}
	if(mVictory)
	{
		string strWinner("Congratulations you won!");
		glRasterPos2i(mWindowWidth/2-125, mWindowHeight/2-25);
		int len = (int)strWinner.size();
		for(int i=0;i<len;i++)
		{
			glutBitmapCharacter(GLUT_BITMAP_HELVETICA_18, strWinner[i]);
		}
		if(mPoints >= 800)
		{
			string strGrade("Grade: A");
			glRasterPos2i(mWindowWidth/2-125, mWindowHeight/2-5);
			len = (int)strGrade.size();
			for(int i=0;i<len;i++)
			{
				glutBitmapCharacter(GLUT_BITMAP_HELVETICA_18, strGrade[i]);
			}
		}
		else if(mPoints < 800 && mPoints >= 700 )
		{
			string strGrade("Grade: B");
			glRasterPos2i(mWindowWidth/2-125, mWindowHeight/2-5);
			len = (int)strGrade.size();
			for(int i=0;i<len;i++)
			{
				glutBitmapCharacter(GLUT_BITMAP_HELVETICA_18, strGrade[i]);
			}
		}
		else if(mPoints < 700 && mPoints >= 550)
		{
			string strGrade("Grade: C");
			glRasterPos2i(mWindowWidth/2-125, mWindowHeight/2-5);
			len = (int)strGrade.size();
			for(int i=0;i<len;i++)
			{
				glutBitmapCharacter(GLUT_BITMAP_HELVETICA_18, strGrade[i]);
			}
		}
		else if(mPoints < 550 && mPoints >= 300)
		{
			string strGrade("Grade: D");
			glRasterPos2i(mWindowWidth/2-125, mWindowHeight/2-5);
			len = (int)strGrade.size();
			for(int i=0;i<len;i++)
			{
				glutBitmapCharacter(GLUT_BITMAP_HELVETICA_18, strGrade[i]);
			}
		}
		else if(mPoints < 300 && mPoints >= 150)
		{
			string strGrade("Grade: E");
			glRasterPos2i(mWindowWidth/2-125, mWindowHeight/2-5);
			len = (int)strGrade.size();
			for(int i=0;i<len;i++)
			{
				glutBitmapCharacter(GLUT_BITMAP_HELVETICA_18, strGrade[i]);
			}
		}
		else 
		{
			string strGrade("Grade: F");
			glRasterPos2i(mWindowWidth/2-125, mWindowHeight/2-5);
			len = (int)strGrade.size();
			for(int i=0;i<len;i++)
			{
				glutBitmapCharacter(GLUT_BITMAP_HELVETICA_18, strGrade[i]);
			}
		}

	}

	//Set semi-transparent crosshair - again a prototype
	glColor4f(1.0f, 0.0f, 0.0f, 0.25f);
	glBegin(GL_QUADS);
		glVertex2i((mWindowWidth/2)-1,(mWindowHeight/2)+15);
		glVertex2i((mWindowWidth/2)+1,(mWindowHeight/2)+15);
		glVertex2i((mWindowWidth/2)+1,(mWindowHeight/2)-15);	
		glVertex2i((mWindowWidth/2)-1,(mWindowHeight/2)-15);

		glVertex2i((mWindowWidth/2)-15, (mWindowHeight/2)+1);
		glVertex2i((mWindowWidth/2)+15, (mWindowHeight/2)+1);
		glVertex2i((mWindowWidth/2)+15, (mWindowHeight/2)-1);
		glVertex2i((mWindowWidth/2)-15, (mWindowHeight/2)-1);

	glEnd();

	////Display as many bullets as are left in the clip
	int currentPos=30;
	for(int i=1; i<mBullets+1; i++)
	{
			
		glRasterPos2i(mWindowWidth-70, mWindowHeight-30 );
		mBulletIconData = corona::FlipImage(mBulletIconData, corona::CA_X);
		
		if(mBulletIconData)
		{
			glPixelStorei(GL_UNPACK_ALIGNMENT, 1);		
			glDrawPixels(mBulletIconData->getWidth(), mBulletIconData->getHeight(), 
				GL_RGBA, GL_UNSIGNED_BYTE, mBulletIconData->getPixels());

			glRasterPos2i(mWindowWidth-70, mWindowHeight-currentPos );
				
			glPixelStorei(GL_UNPACK_ALIGNMENT, 1);		
				glDrawPixels(mBulletIconData->getWidth(), mBulletIconData->getHeight(), 
				GL_RGBA, GL_UNSIGNED_BYTE, mBulletIconData->getPixels());

			currentPos=currentPos+20;

		}
	}
	glEnable(GL_LIGHTING);
	//Set back to Projection matrix and pop
	glMatrixMode(GL_PROJECTION);

	glPopMatrix();

	//Set model view
	glMatrixMode(GL_MODELVIEW);

}

//Inits bullet images
void cDisplayManager::SetupBulletImage()
{
	mBulletIconData = corona::OpenImage("./textures/bullet_icon.tga", corona::PF_R8G8B8A8);
}

//Sets direction damage comes from
void cDisplayManager::SetDamageDirection(int d)
{
	mDamageDirection=d;
}

//Gets damage direction
int cDisplayManager::GetDamageDirection()
{
	return mDamageDirection;
}

//Sets bullet count
void cDisplayManager::SetBullets(int b)
{
	mBullets = b;
}

//Gets bullet count
int cDisplayManager::GetBullets()
{
	return mBullets;
}

//Gets bounding bodies
std::vector<cBounding>* cDisplayManager::GetBoundingBody()
{
	return &mBody;
}

//Reloads a gun to its max bullets after 2 seconds
void cDisplayManager::Reload(float elapsedTimeS)
{
	static float reloadTime=2.0f;
	static float currentTime=0.0f;

	cGunManager* pGunManager = GetGunManager();
	if(currentTime<reloadTime)
	{
		currentTime=currentTime+elapsedTimeS;
	}
	else
	{
		mBullets = pGunManager->GetBullets();
		currentTime=0.0f;
	}
}

//Delays fire rate for 1/2 seconds
void cDisplayManager::FireDelay(float elapsedTimeS)
{
	static float delayTime = 0.5f;
	static float currentTime = 0.0f;

	if(currentTime < delayTime)
	{
		currentTime += elapsedTimeS;
	}
	else
	{
		mFireRate = 0;
		currentTime = 0.0f;
	}
}

//Sets health
void cDisplayManager::SetHealth(int h)
{
	mHealth = h;
}

//Gets health
int cDisplayManager::GetHealth()
{
	return mHealth;
}

//Sets dead status
void cDisplayManager::SetDead(int dead)
{
	mDead = dead;
}

//Gets dead status
int cDisplayManager::GetDead()
{
	return mDead;
}

//Sets fire rate 
void cDisplayManager::SetFireRate(int firerate)
{
	mFireRate = firerate;
}

//Gets fire rate
int cDisplayManager::GetFireRate()
{
	return mFireRate;
}

//Gets status
bool cDisplayManager::GetStatus()
{
	return mStatus;
}

//Sets status
void cDisplayManager::SetStatus(bool s)
{
	mStatus=s;
}

//Adds bounding sphere to bodies
void cDisplayManager::AddBody(float x, float y, float z, float r)
{
	cBounding* newBounding = GetBounding();
	newBounding->SetSphere(x,y,z,r,kSphereBody);
	mBody.push_back(*newBounding);
}

//Updates spheres
void cDisplayManager::UpdateBody(float x, float y, float z, float r, int pos)
{
	mBody[pos].SetSphere(x,y,z,r, kSphereBody);
}

//Sets points
void cDisplayManager::SetPoints(int p)
{
	mPoints = p;
}

//Gets points
int cDisplayManager::GetPoints()
{
	return mPoints;
}

//Gets forwards speed
float cDisplayManager::GetFSpeed()
{
	return mForwardSpeed;
}

//Gets strafe speed
float cDisplayManager::GetSSpeed()
{	
	return mStrafeSpeed;
}

//SEts X position
void cDisplayManager::SetCameraX(float x)
{
	mCameraPosition[0]=x;
}

//Sets Z position
void cDisplayManager::SetCameraZ(float z)
{
	mCameraPosition[2]=z;
}

//Draws a vertical warning bar
void cDisplayManager::DrawVertWarningBar(int hpos, int vpos)
{
	glColor4f(1.0f,0.0f,0.0f, 0.5f);
	glBegin(GL_QUADS);
		glVertex2i(hpos,vpos);
		glVertex2i(hpos+30,vpos);
		glVertex2i(hpos+30,vpos-300);	
		glVertex2i(hpos,vpos-300);
	glEnd();
}

//Draws a horizontal warning bar
void cDisplayManager::DrawHorzWarningBar(int hpos, int vpos)
{
	glColor4f(1.0f,0.0f,0.0f, 0.5f);
	glBegin(GL_QUADS);
		glVertex2i(hpos,vpos);
		glVertex2i(hpos+300,vpos);
		glVertex2i(hpos+300,vpos-30);	
		glVertex2i(hpos,vpos-30);
	glEnd();
}